home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / PROBLEMS / C / UFN_ROFN < prev   
Text File  |  1991-04-28  |  11KB  |  343 lines

  1. /*
  2.  
  3.  
  4.    Recetly I noticed a lot of talk about a routine to convert UNIX 
  5.    filenames to RISC OS filenames, but as of yet no one has come up
  6.    with the goods !
  7.    
  8.    So to start the ball rolling I'll post this rather awful routine
  9.    which does the job. It's written in C and is probably too 
  10.    unintelligible to be ported to any other language. I use it in my
  11.    programs - which I've just posted, and it hasn't failed me yet.
  12.    When compiling, try :
  13.   
  14.    cc c.ufn_rofn -DTEST 
  15.    
  16.    if you want to test it out.
  17.  
  18.    That's all folks !
  19.    
  20.    Steven van Aardt 
  21.  
  22.    (If we've any Dutch Users I'd like your opinion of the origins 
  23.     of my surname, it apparently has an Afrikanns background.)
  24.                         
  25. -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
  26. | | | | | | | | | | | |  C U T   B E L O W  | | | | | | | | | | | | | | | | |
  27. '-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'
  28.  
  29. */
  30. /*----------------------------------------------------*
  31.  * Module : c.ufn_rofn
  32.  * Purpose: Convert UNIX filenames to RiscOS filename
  33.  * Author : Steven van Aardt
  34.  *----------------------------------------------------*/
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39.  
  40. #define FALSE 0
  41. #define TRUE (!FALSE)
  42.  
  43. #define MAX_FILENAME 10
  44.  
  45. /*---------------------------- Reverse ------------------------*
  46.  * Purpose:   Reverse the character sequence within a string
  47.  * Arguments: Pointer to string
  48.  * Returns:   Pointer to the same string given as an argument.
  49.  *-------------------------------------------------------------*/
  50. static
  51. char *reverse(char *string)
  52. {
  53.   int hd=0,tl=strlen(string);
  54.   char tmp_c;
  55.   /* reverse the name */
  56.   while (--tl>hd) {                   /* work way back from end of string */
  57.     tmp_c=string[hd];
  58.     string[hd++]=string[tl];
  59.     string[tl]=tmp_c;
  60.   }
  61.   return string;
  62. }
  63.  
  64. /*---------------------------- isvowel --------------------------------*
  65.  * Purpose:   Determines whether a character is an alphabetical vowel
  66.  * Arguments: character (integer form)
  67.  * Returns:   TRUE if vowel, otherwise FALSE.
  68.  *---------------------------------------------------------------------*/
  69. static
  70. int isvowel(int c)
  71. {
  72.   int vowel=FALSE;
  73.   switch (c) {
  74.     case 'a': case 'A':             /* if c matches with */
  75.     case 'e': case 'E':             /* any of these function */
  76.     case 'i': case 'I':             /* will return TRUE */
  77.     case 'o': case 'O':
  78.     case 'u': case 'U': vowel=TRUE;
  79.   }
  80.   return vowel;
  81. }
  82.  
  83. /*--------------------  squeeze  ------------------------*
  84.  * Purpose:   remove any space characters from a string
  85.  * Arguments: pointer to string
  86.  * Returns:   pointer to a new string.
  87.  *-------------------------------------------------------*/
  88. static
  89. char *squeeze(char *ptr)
  90. {
  91.    int  i=0,j=0;
  92.    char *nn=NULL;
  93.    /* squeeze in-place */
  94.    for (i=j=0; ptr[i]!='\0';i++) if (ptr[i]!=' ') ptr[j++]=ptr[i];
  95.    /* and copy into a new string */
  96.    nn=calloc(j+2,sizeof(char)); /* allocate enough memory for new string */
  97.    strncpy(nn,ptr,j);
  98.    return nn;
  99. }
  100.  
  101. /*---------------------------- rm_vowels -----------------------------*
  102.  * Purpose:   removes some vowels from a string thus shortening it
  103.  * Arguments: pointer to string
  104.  * Returns:   pointer to a new string.
  105.  *--------------------------------------------------------------------*/
  106. static
  107. char *rm_vowels(char *word,int maxlen)
  108. {
  109.   char *new_word=NULL;
  110.   if (word) {
  111.     int len=strlen(word);
  112.     char *cpy=calloc(len+1,sizeof(char));
  113.     strcpy(cpy,word);
  114.     if (len>maxlen) { 
  115.       /* remove every 2nd vowel */
  116.       int i;
  117.       len--;  /* leave last letter */
  118.       for (i=1; i<len; i+=2) {
  119.         while ((i<len) && (!isvowel(cpy[i]))) i++; /* skip non-vowels */ 
  120.         if ((i<len) && (isvowel(cpy[i]))) cpy[i]=' '; /* overwrite vowels */
  121.       }
  122.     }
  123.     new_word=squeeze(cpy); 
  124.     free(cpy);
  125.   }
  126.   return new_word;
  127. }
  128.  
  129. /*-------------------  shorten  ----------------------*
  130.  * Purpose:   Shortens a string to a specified length
  131.  * Arguments: pointer to string
  132.  *            max length of string to be.
  133.  * Returns: Pointer to new string
  134.  *----------------------------------------------------*/
  135. static
  136. char *shorten(char *ptr,int maxlen)
  137. {
  138.   char *new_ptr;
  139.   int l=strlen(ptr);
  140.   if (l>maxlen) {
  141.     /* quick shortening by removing a chunk from the middle */
  142.     int num=l-maxlen; /* number to remove to get length of 10 */
  143.     int i,j=0;
  144.     for (i=(l-num)/2; j<num; j++) ptr[i+j]=' ';
  145.   }
  146.   new_ptr=squeeze(ptr);
  147.   return new_ptr;
  148. }
  149.  
  150.  
  151.  
  152. /*--------------------- ufn_rofn ------------------------*
  153.  * Purpose:   Convert UNIX filename to RISC OS filename 
  154.  * Arguments: pointer to UNIX filename string
  155.  * Returns:   pointer to RISC OS filename
  156.  *-------------------------------------------------------*/
  157. extern
  158. char *ufn_rofn(char *unix_name)
  159. {
  160.   typedef struct l List;         /* structure for constituent parts */
  161.   struct l { char *ptr; struct l *last,*next; };
  162.   int  len;
  163.   char *uname=calloc(strlen(unix_name)+1,sizeof(char)),*rname=NULL,*ptr=NULL;
  164.   List *lptr=NULL,*hdptr=NULL,*tlptr=NULL;
  165.   while ((unix_name) && (*unix_name==' ')) unix_name++;
  166.   if ((unix_name) && (*unix_name)) {
  167.     strcpy(uname,unix_name);
  168.     /* look for root directory '/' at beginning of unix filename */
  169.     if (uname[0]=='/') {
  170.       char *tmp=calloc(2,sizeof(char));
  171.       strcpy(tmp,"$");
  172.       lptr=(List *) malloc(sizeof(List));
  173.       tlptr=lptr;         /* pointer to beginning of list */
  174.       lptr->ptr=tmp;      
  175.       lptr->next=NULL;
  176.       lptr->last=hdptr;
  177.       hdptr=lptr;         /* pointer to end of list */
  178.     }
  179.    /*
  180.     *   Break down the name into its directory components - destroys uname
  181.     */
  182.     ptr=strtok(uname,"/");          /* ignores / if at beginning of list */
  183.     while (ptr) {
  184.       char *tmp=calloc(strlen(ptr)+1,sizeof(char));
  185.       strcpy(tmp,ptr);
  186.       lptr=(List *) malloc(sizeof(List));
  187.       if (!tlptr) tlptr=lptr;      /* make pointer to beginning of list */
  188.       if (hdptr) hdptr->next=lptr; /* link previous element onto this */
  189.       lptr->ptr=tmp;
  190.       lptr->next=NULL;   
  191.       lptr->last=hdptr;  /* reverse chained list */
  192.       hdptr=lptr;
  193.       ptr=strtok(NULL,"/");        /* find next '/' */
  194.     }
  195.     /*
  196.      *  Now go through each component looking for a '.' within each.
  197.      */
  198.     lptr=tlptr;                     /* beginning of list */
  199.     while (lptr) {
  200.       char *dp=NULL;                /* dot position */
  201.       dp=strchr(lptr->ptr,'.');
  202.       if (dp) {
  203.         int len=strlen(lptr->ptr);
  204.         /* 
  205.          * special cases
  206.          */
  207.         /* if only 1 dot then refers to the UNIX csd */
  208.         if (len==1) { 
  209.           char *tmp=calloc(2,sizeof(char));
  210.           strcpy(tmp,"@");
  211.           lptr->ptr=tmp;
  212.         } else {
  213.           if (len==2) { 
  214.             char *tmp=calloc(2,sizeof(char)); 
  215.             strcpy(tmp,"^");
  216.             lptr->ptr=tmp;
  217.           } else {
  218.             /* 
  219.              * General case requires reversing of parts around '.'
  220.              */
  221.             List *dlptr=NULL, *dhdptr=NULL, *dtlptr=NULL,*tmp_next=lptr->next;
  222.             char *dptr=NULL,*cpy=calloc(len+1,sizeof(char));
  223.  
  224.             strcpy(cpy,lptr->ptr);
  225.             reverse(cpy);           /* reverse complete text */
  226.             dptr=strtok(cpy,".");
  227.             while (dptr) {
  228.               char *tmp=calloc(strlen(dptr)+1,sizeof(char));  
  229.               strcpy(tmp,dptr); /* make a copy of part */ 
  230.               dlptr=(List *) malloc(sizeof(List));
  231.               if (!dtlptr) dtlptr=dlptr;  /* remember beginning of this list */
  232.               if (dhdptr) dhdptr->next=dlptr; /* link previous one onto this */
  233.               dlptr->ptr=reverse(tmp); /* and reverse it's text back again */
  234.               dlptr->next=NULL;
  235.               dlptr->last=dhdptr;  /* reverse chaining  */
  236.               dhdptr=dlptr;
  237.               dptr=strtok(NULL,".");
  238.             } /* endwhile */
  239.             if (lptr->last) {
  240.               free(lptr->ptr);       /* free text worked on by above */
  241.               lptr=lptr->last;       /* move back */
  242.               free(lptr->next);      /* free text's list element */
  243.               lptr->next=dtlptr;     /* link */
  244.               dtlptr->last=lptr;
  245.               dlptr->next=tmp_next;
  246.               if (tmp_next) { 
  247.                 tmp_next->last=dlptr;
  248.                 lptr=tmp_next->last;
  249.               } else lptr=dlptr;
  250.             } else {        /* case when this is the head of the list */
  251.               free(lptr->ptr);
  252.               free(lptr);
  253.               lptr=dtlptr;
  254.               tlptr=lptr;
  255.               lptr->last=NULL;
  256.               dlptr->next=tmp_next;
  257.               if (tmp_next) {
  258.                 tmp_next->last=dlptr;
  259.                 lptr=tmp_next->last;
  260.               } else lptr=dlptr;
  261.             } /* endif */
  262.           } /* endif */
  263.         } /* endif */
  264.       } /* endif */ 
  265.       lptr=lptr->next; /* move onto next directory component in list */
  266.     } /* endwhile */
  267.     /* 
  268.      *  Check the lengths of each component and adjust to that for RISC OS
  269.      */
  270.     lptr=tlptr;
  271.     len=0;
  272.     while (lptr) {
  273.       char *new_ptr=NULL;
  274.       if (lptr->next) len+=1;  /* for the RISC OS directory separator */
  275.       new_ptr=rm_vowels(lptr->ptr,MAX_FILENAME);
  276.       free(lptr->ptr);
  277.       lptr->ptr=new_ptr;
  278.       new_ptr=shorten(lptr->ptr,MAX_FILENAME);
  279.       free(lptr->ptr);
  280.       lptr->ptr=new_ptr;
  281.       len+=strlen(lptr->ptr);
  282.       lptr=lptr->next;
  283.     }
  284.     /*
  285.      *  Copy linked list into result string
  286.      */
  287.     rname=calloc(len+1,sizeof(char)); /* make suitable string space */
  288.     lptr=tlptr;
  289.     len=0;
  290.     while (lptr) {
  291.       strcat((rname+len),lptr->ptr);
  292.       free(lptr->ptr);     
  293.       len=strlen(rname);
  294.       lptr=lptr->next;
  295.       if (lptr) strcat(rname,"."); /* append RISC OS directory separator */
  296.     }
  297.     /*
  298.      *  Tidy up, by freeing memory used by list
  299.      */
  300.     lptr=tlptr;
  301.     while (lptr) {
  302.       List *tmp;
  303.       tmp=lptr;
  304.       lptr=lptr->next;
  305.       free(tmp);
  306.     }
  307.   } /* endif */
  308.   free(uname);
  309.   return rname;
  310. }
  311.  
  312.  
  313.  
  314.  
  315. #ifdef TEST
  316.  
  317. int main(void) {
  318.   char unix_filename[256],*riscos_filename;
  319.  
  320.   while (!feof(stdin)) {
  321.      printf("Enter Unix filename : ");
  322.      scanf("%s",&unix_filename);
  323.      if (!feof(stdin)) {
  324.        riscos_filename=ufn_rofn(unix_filename);
  325.        printf("Risc OS filename    : %s\n",riscos_filename);
  326.        free(riscos_filename);
  327.      }
  328.   }
  329.   return 0;
  330. }
  331.  
  332. #endif
  333.  
  334. /*
  335. +--------------------------------+-----------------------------------------+
  336. |   ()()TEVEN         ()         |                                         |  
  337. |  ()                ()()        |                                         |  
  338. |   ()()   ()  ()AN ()  ()       |                                         |
  339. |      ()   ()()   ()()()()      +-----------------------------------------+
  340. |   ()()     ()   ()      ()ARDT |JANET E-mail : vanaards@uk.ac.man.cs.p4  |
  341. +--------------------------------+-----------------------------------------+
  342. */
  343.